package com.example.blue_classic_plus;

import static android.app.Activity.RESULT_CANCELED;
import static android.app.Activity.RESULT_OK;

import android.app.Activity;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;

import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import com.example.blue_classic_plus.ble.BleClient;
import com.example.blue_classic_plus.ble.BleServer;

import java.util.HashMap;
import java.util.Map;

import io.flutter.embedding.engine.plugins.FlutterPlugin;
import io.flutter.embedding.engine.plugins.activity.ActivityAware;
import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding;
import io.flutter.plugin.common.EventChannel;
import io.flutter.plugin.common.MethodCall;
import io.flutter.plugin.common.MethodChannel;
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.common.PluginRegistry;

/**
 * BlueClassicPlusPlugin
 */
public class BlueClassicPlusPlugin implements FlutterPlugin, MethodCallHandler, ActivityAware, PluginRegistry.ActivityResultListener {

    private MethodChannel channel;

    private EventChannel.EventSink sink;

    private Activity activity;

    ///打开蓝牙
    public static final int REQUEST_ENABLE_BT = 0x11;

    ///打开检测性
    public static final int REQUEST_ENABLE_Eetectability = 0x12;

    BleServer bleServer;

    BleClient bleClient;

    Result result;

    BluetoothAdapter bluetoothAdapter = BluetoothAdapter.getDefaultAdapter();

    ///注册 BroadcastReceiver 来接收蓝牙设备发现的广播
    private final BroadcastReceiver receiver = new BroadcastReceiver() {
        public void onReceive(Context context, Intent intent) {
            String action = intent.getAction();
            if (BluetoothDevice.ACTION_FOUND.equals(action)) {
                BluetoothDevice device = intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE);
                if (device != null && !TextUtils.isEmpty(device.getName())) {
                    //System.out.println("发现设备 name:" + device.getName() + " ,address:" + device.getAddress());

                    Map<String, Object> map = new HashMap<>();
                    map.put("type", "bluetoothStartDiscovery");
                    map.put("name", device.getName());
                    map.put("address", device.getAddress());
                    sink.success(map);
                }
            }
        }
    };

    ///Sink 在主线程通知Flutter
    private Handler handler = new Handler(new Handler.Callback() {
        @Override
        public boolean handleMessage(Message msg) {

            sink.success(msg.obj);
            return true;
        }
    });

    @Override
    public void onAttachedToEngine(@NonNull FlutterPluginBinding flutterPluginBinding) {
        channel = new MethodChannel(flutterPluginBinding.getBinaryMessenger(), "blue_classic_plus");
        channel.setMethodCallHandler(this);

        //初始化事件通道，主要是获取这个EventChannel.EventSink sink，用这个sink发消息给flutter
        new EventChannel(flutterPluginBinding.getBinaryMessenger(), "blue_classic_plus_eventChannel").setStreamHandler(new EventChannel.StreamHandler() {
            @Override
            public void onListen(Object o, EventChannel.EventSink eventSink) {
                sink = eventSink;
            }

            @Override
            public void onCancel(Object o) {
                sink = null;
            }
        });
    }

    @Override
    public void onMethodCall(@NonNull MethodCall call, @NonNull Result result) {
        HashMap argumentsMap = (HashMap) call.arguments;
        if (call.method.equals("getPlatformVersion")) {
            result.success("Android " + android.os.Build.VERSION.RELEASE);
        } else if (call.method.equals("bluetoothIsSupport")) {
            ///检测蓝牙是否可用
            boolean isSupport = bluetoothAdapter != null && bluetoothAdapter.isEnabled();
            result.success(isSupport);
        } else if (call.method.equals("bluetoothIsEnabled")) {
            this.result = result;
            ///打开蓝牙
            Intent enableBtIntent = new Intent(BluetoothAdapter.ACTION_REQUEST_ENABLE);
            activity.startActivityForResult(enableBtIntent, REQUEST_ENABLE_BT);
        } else if (call.method.equals("bluetoothEnableEetectability")) {
            this.result = result;
            ///打开蓝牙可检测性：300秒
            Intent discoverableIntent =
                    new Intent(BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE);
            discoverableIntent.putExtra(BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION, 300);

            activity.startActivityForResult(discoverableIntent, REQUEST_ENABLE_Eetectability);
        } else if (call.method.equals("bluetoothStartDiscovery")) {

            if (bleClient != null && bleClient.isConnecting) {
                System.out.println("客户端是连接状态，不用重复连接");
                return;
            }

            ///连接设备
            String uuid = argumentsMap.get("uuid").toString();
            String name = argumentsMap.get("name").toString();

             bleClient = new BleClient(activity,uuid,name,handler);
             bleClient.startScan();

        } else if (call.method.equals("bluetoothEndDiscovery")) {
            ///结束扫描
            bleClient.stopScan();

        }
        else if (call.method.equals("bluetoothStartServer")) {
            ///服务端启动
            String uuid = argumentsMap.get("uuid").toString();
            String name = argumentsMap.get("name").toString();

            ///判断一下
            if (bleServer != null && bleServer.serverListening) {
                System.out.println("服务端开启中，不需要重复开启");
                return;
            }

            bleServer = new BleServer(activity,uuid,name,handler);
            bleServer.startAdvertising(activity);


        } else if (call.method.equals("bluetoothStopServer")) {
            ///关闭服务端
            if (bleServer == null) return;
            bleServer.stopServer();

        } else if (call.method.equals("bluetoothStopClient")) {
            ///客户端关闭连接
            if (bleClient == null) return;

            bleClient.stopConnect();

        } else if (call.method.equals("bluetoothServerBroadcastMsg")) {
            ///服务端广播消息
            String msg = argumentsMap.get("msg").toString();
            if (TextUtils.isEmpty(msg)) return;

            if (bleServer != null && bleServer.serverListening) {
                bleServer.broadcastData(msg);
            }
        } else if (call.method.equals("bluetoothClientSendMsg")) {
            ///客户端发送消息
        } else {
            result.notImplemented();
        }
    }


    @Override
    public boolean onActivityResult(int requestCode, int resultCode, @Nullable Intent data) {
        System.out.println("requestCode:" + requestCode + " ,resultCode:" + requestCode);

        if (requestCode == REQUEST_ENABLE_BT) {
            ///打开蓝牙结果
            if (result != null) {
                result.success(resultCode == RESULT_OK);
            }
            return true;
        } else if (requestCode == REQUEST_ENABLE_Eetectability) {
            ///打开蓝牙可见性
            if (result != null) {
                result.success(resultCode != RESULT_CANCELED);
            }
            return true;
        }

        return false;
    }


    @Override
    public void onDetachedFromEngine(@NonNull FlutterPluginBinding binding) {
        channel.setMethodCallHandler(null);
    }


    @Override
    public void onAttachedToActivity(@NonNull ActivityPluginBinding activityPluginBinding) {
        activityPluginBinding.addActivityResultListener(this);
        activity = activityPluginBinding.getActivity();
    }

    @Override
    public void onDetachedFromActivityForConfigChanges() {
        this.onDetachedFromActivity();
    }

    @Override
    public void onReattachedToActivityForConfigChanges(@NonNull ActivityPluginBinding activityPluginBinding) {
        this.onAttachedToActivity(activityPluginBinding);
    }

    @Override
    public void onDetachedFromActivity() {
        activity = null;
    }
}
